package work.huangxin.share.redisListenter;

import org.simpleframework.xml.util.Entry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import work.huangxin.share.constant.RedisConstant;
import work.huangxin.share.domain.admin.UserBlock;
import work.huangxin.share.mapper.UserMessageMapper;
import work.huangxin.share.service.AdminUserService;
import work.huangxin.share.util.RedisUtil;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @Author: 钟声浩
 * @Date: 2023-04-09 16:45
 * @Desc: 1. 若Redis宕机，则从数据库中读取还在拉黑的用户
 *        2. 过期时间到了，操作数据库
 */
@Component
public class BlockListInitializer implements ApplicationListener<ContextRefreshedEvent> {

    @Autowired
    private AdminUserService adminUserService;

    @Autowired
    private RedisUtil redisUtil;


    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;

//    @Autowired
//    private CompletableFuture completableFuture;




    //在程序启动时，将数据库中的数据放入redis中
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        //检查程序是否是重新启动
        if (event.getApplicationContext().getParent() == null) {
            syncBlockList();
        }
    }


    //若是使用CountDownLatch，若操作失败，可能会一直处于等待状态。
    private void syncBlockList() {
        //得到所有被拉黑的用户（被deleted的除外）
        List<UserBlock> userBlockList = adminUserService.selectAllBlock();
        if (userBlockList != null && !userBlockList.isEmpty()) {
            long nowTime = System.currentTimeMillis();
            Map<String, Long> blockMap = new HashMap<>();
            //将拉黑，但是时间没过期，且没被删除的用户，放进map中
            for (UserBlock userBlock : userBlockList) {
                if (userBlock.getExpireTime() > nowTime) {
                    long diffTime = userBlock.getExpireTime() - nowTime;
                    blockMap.put(RedisConstant.USER_BLOCK_LIST + userBlock.getUserId(), diffTime);
                } else {
                    //子线程执行删除过期的数据任务
                    //过期的拉黑用户
                    threadPoolExecutor.execute(() -> {
                        //数据库中对已经过期的数据不再同步到Redis中，并且将对应的 deleted 设置为 1
                        adminUserService.unlockUserAndAllow(userBlock.getUserId());
                    });
                }
            }
            if (!blockMap.isEmpty()) {
                for (Map.Entry<String, Long> entry : blockMap.entrySet()) {
                    redisUtil.sSetAndTime(entry.getKey(), entry.getValue(), "");
                }
            }
        }
    }
}
